package com.ruoyi.common.utils.oss;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

import org.springframework.stereotype.Component;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.aliyun.oss.model.DeleteObjectsResult;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.ruoyi.common.utils.OrderNumberGeneratorUtil;

/**
 * 阿里云OSS 工具类
 * @author DEREK
 */
@Component
public class OSSStsUtil {
	/** 目前只有"cn-hangzhou"这个region可用, 不要使用填写其他region的值 */
	private static final String REGION_CN_HANGZHOU = "cn-beijing";

	private static final String BUCKETNAME = "xinyangxiong";
	/** 必须是https请求 */
	private static final ProtocolType PROTOCOL_TYPE = ProtocolType.HTTPS;
	/** 指定角色的全局资源描述符(Aliyun Resource Name，简称Arn) */
	private static final String ROLE_ARN = "acs:ram::1193083392949088:role/aliyunosstokengeneratorrole";
	/** 用户自定义参数。此参数用来区分不同的Token，可用于用户级别的访问审计 */
	private static final String ROLE_SESSION_NAME = "ROLEOSSUPLOAD";

	private static final String ENDPOINT = "http://oss-cn-beijing.aliyuncs.com/";

	private static final String ACCESSKEYID = "LTAI5tPwCw7c7fwVok5ucJF6";

	private static final String ACCESSKEYSECRET = "HBmEkcowHvDxM32qxkqwxUslv3V7Bv";

	
	/**
	 * 社交OSS
	 * kuoyouapp
	 * AccessKey ID ： LTAI5tE1riR7CDds3R4uoeyA
	 * accesskeysecret ： xGLA9wssSSCNnwhoa8L2LFoILoHaaC
	 * Endpoint ： oss-cn-beijing.aliyuncs.com
	 * Bucket 域名 ： kuoyouapp.oss-cn-beijing.aliyuncs.com
	 * 
	 */
	

	public AssumeRoleResponse.Credentials getToken() throws ClientException {
		String bucketName = "";
		String accessKeyId = "";
		String accessKeySecret = "";
		Long expirationTime = 900L;
		AssumeRoleResponse.Credentials credentials = createSTSForPutObject(bucketName, ROLE_ARN, accessKeyId,
				accessKeySecret, expirationTime);
		return credentials;
	}

	//public static void main(String[] args) throws ClientException {

	/*
	 * String bucketName = "miyu2app"; String accessKeyId =
	 * "LTAI4GAGN3weBup39hR9xX4D"; String accessKeySecret =
	 * "bUgCEYbiRRGxqFpIcormi5201w0h58"; String endpoint =
	 * "http://oss-cn-hangzhou.aliyuncs.com/"; Long expirationTime = 900L;
	 * AssumeRoleResponse.Credentials credentials =
	 * createSTSForPutObject(bucketName, ROLE_ARN, accessKeyId, accessKeySecret,
	 * expirationTime); System.out.println(credentials);

		deleteKey("html/templates/invite.html");*/

	//}

	/**
	 * 创建上传临时账号
	 * 
	 * @param bucketName
	 * @param roleArn         需要授权的角色名称
	 * @param accessKeyId     账号
	 * @param accessKeySecret 密码
	 * @param expirationTime  过期时间，单位为秒
	 * @return
	 */
	public static AssumeRoleResponse.Credentials createSTSForPutObject(String bucketName, String roleArn,
			String accessKeyId, String accessKeySecret, Long expirationTime) throws ClientException {
		String policy = OSSStsUtil.getPutObjectPolicy(bucketName);
		return createSTS(policy, roleArn, accessKeyId, accessKeySecret, expirationTime);
	}

	/**
	 * 创建只读临时授权
	 * 
	 * @param bucketName
	 * @param roleArn         需要授权的角色名称
	 * @param accessKeyId     账号
	 * @param accessKeySecret 密码
	 * @param expirationTime  过期时间，单位为秒
	 * @return
	 */
	public static AssumeRoleResponse.Credentials createSTSForReadOnly(String bucketName, String roleArn,
			String accessKeyId, String accessKeySecret, Long expirationTime) throws ClientException {
		String policy = OSSStsUtil.getOSSReadOnlyAccessPolicy(bucketName);
		return createSTS(policy, roleArn, accessKeyId, accessKeySecret, expirationTime);
	}

	/**
	 * 创建STS
	 * 
	 * @param policy          授权策略
	 * @param roleArn         需要授权的角色名称
	 * @param accessKeyId     账号
	 * @param accessKeySecret 密码
	 * @param expirationTime  过期时间，单位为秒
	 * @return
	 */
	@SuppressWarnings("deprecation")
	private static AssumeRoleResponse.Credentials createSTS(String policy, String roleArn, String accessKeyId,
			String accessKeySecret, Long expirationTime) throws ClientException {
		IClientProfile profile = DefaultProfile.getProfile(REGION_CN_HANGZHOU, accessKeyId, accessKeySecret);
		DefaultAcsClient client = new DefaultAcsClient(profile);
		final AssumeRoleRequest request = new AssumeRoleRequest();
		request.setDurationSeconds(expirationTime);
		//        request.setVersion(STS_API_VERSION);
		request.setSysMethod(MethodType.POST);
		request.setSysProtocol(PROTOCOL_TYPE);
		request.setMethod(MethodType.POST);
		request.setProtocol(PROTOCOL_TYPE);
		request.setRoleArn(roleArn);
		request.setRoleSessionName(ROLE_SESSION_NAME);
		//        request.setPolicy(policy);
		// 实体用户获取角色身份的安全令牌的方法
		AssumeRoleResponse response = client.getAcsResponse(request);
		AssumeRoleResponse.Credentials credentials = response.getCredentials();
		return credentials;
	}

	/**
	 * 自定义授权策略，对当前bucket下的文件夹读写
	 * 
	 * @param bucketName
	 * @return
	 */
	private static String getPutObjectPolicy(String bucketName) {
		return String.format(
				"{\n" + "    \"Version\": \"1\", \n" + "    \"Statement\": [\n" + "        {\n"
						+ "            \"Action\": [\n" + "                \"oss:*\" \n" + "            ], \n"
						+ "            \"Resource\": [\n" + "                \"acs:oss:*:*:%s/*\"\n"
						+ "            ], \n" + "            \"Effect\": \"Allow\"\n" + "        }\n" + "    ]\n" + "}",
						bucketName);
		//        return String.format(
		//                "{\n" +
		//                        "    \"Version\": \"1\", \n" +
		//                        "    \"Statement\": [\n" +
		//                        "        {\n" +
		//                        "            \"Action\": [\n" +
		//                        "                \"oss:PutObject\" \n" +
		//                        "            ], \n" +
		//                        "            \"Resource\": [\n" +
		//                        "                \"acs:oss:*:*:%s/*\"\n" +
		//                        "            ], \n" +
		//                        "            \"Effect\": \"Allow\"\n" +
		//                        "        }\n" +
		//                        "    ]\n" +
		//                        "}", bucketName);
	}

	/**
	 * 只读访问该bucket对象存储服务(OSS)的权限，授权策略
	 * 
	 * @param bucketName
	 * @return
	 */
	private static String getOSSReadOnlyAccessPolicy(String bucketName) {
		return String.format("{\n" + "  \"Statement\": [\n" + "    {\n" + "      \"Action\": [\n"
				+ "        \"oss:Get*\",\n" + "        \"oss:List*\"\n" + "      ],\n"
				+ "      \"Effect\": \"Allow\",\n" + "      \"Resource\": [\n" + "        \"acs:oss:*:*:%s/*\"\n"
				+ "      ]\n" + "    }\n" + "  ],\n" + "  \"Version\": \"1\"\n" + "}", bucketName);
	}

	public static void deleteKey(String objectName) {
		if(!objectName.contains("default")) {
			OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESSKEYID, ACCESSKEYSECRET);
			try {		
				ossClient.deleteObject(BUCKETNAME, objectName);
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				ossClient.shutdown();
			}	
		}
	}

	public static void deleteKeys(List<String> keys) {
		OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESSKEYID, ACCESSKEYSECRET);
		try {
			DeleteObjectsResult deleteObjectsResult = ossClient
					.deleteObjects(new DeleteObjectsRequest(BUCKETNAME).withKeys(keys));
			deleteObjectsResult.getDeletedObjects();
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			ossClient.shutdown();
		}	
	}

	public static boolean isExist(String path) {
		OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESSKEYID, ACCESSKEYSECRET);
		boolean doesObjectExist = ossClient.doesObjectExist(BUCKETNAME, path);
		return doesObjectExist;
	}

	/**
	 * 文件路径
	 * @param suffix 后缀
	 * @return 返回上传路径
	 */
	public static String getPath(String suffix) {
		String path = "auth/"+OrderNumberGeneratorUtil.get();
		return path + suffix;
	}

	/**
	 * 	上传图片到OSS
	 * @param url
	 * @return
	 */
	public static String upload(String url) {
		String path = getPath(".png");
		try {
			OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESSKEYID, ACCESSKEYSECRET);
			InputStream inputStream = new URL(url).openStream();
			ossClient.putObject(BUCKETNAME, path, inputStream);
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return path;
	}

	public static void main(String[] args) throws MalformedURLException, IOException {
		// Endpoint以杭州为例，其它Region请按实际情况填写。
		// 阿里云主账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维，请登录 https://ram.console.aliyun.com 创建RAM账号。
//		String objectName = "avatar/8/2020/07/10/8f67a67eb9d14859ab582c2eb22d427e_small.png";
//
//		// 创建OSSClient实例。
//		OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESSKEYID, ACCESSKEYSECRET);
//
//		// 删除文件。如需删除文件夹，请将ObjectName设置为对应的文件夹名称。如果文件夹非空，则需要将文件夹下的所有object删除后才能删除该文件夹。
//		ossClient.deleteObject(BUCKETNAME, objectName);
//		System.out.println("删除");
//		// 关闭OSSClient。
//		ossClient.shutdown();
//		upload("https://xinyangxiong.oss-cn-beijing.aliyuncs.com/sysIcon/80.png");
		deleteKey("pic/165226940920464.jpg");
	}
}
